package futbol.tacticas.concursantes.TacticaDRX;

import futbol.tacticas.*;
import futbol.tacticas.concursantes.Tactica;
import java.awt.*;
import java.util.*;

public class TacticaDRX implements Tactica {
	
	private static int MAXX=160;
	private static int MAXY=120;
	private static int LONGX=MAXX*2;
	private static int LONGY=MAXY*2;
    
    Random rand=new Random();
    
    /**Nombre del Equipo*/
    public String getNombre() {
        return "DRX 3.2.4 FC";
    }
    
    
    /**Color de la camiseta*/
    public Color getColor1() {
        return Color.black;
    }
    /**Color del pantalon*/
    public Color getColor2() {
        return Color.black;
    }
    /**Color del numero*/
    public Color getColorNumero() {
        return Color.white;
    }
    
    public final int fuerza[]=sfuerza;
    public static int sfuerza[]=new int[]
    {7,7, 6,6, 6,6, 7,7 ,7,7,7};
    //{7,7, 6,6, 6,6, 7,7 ,7,7,7};
    
    private int posiciones[][]=sposiciones;
    public static int sposiciones[][]=new int[][]
    {{-140,15},{-140,-15}, {-60,60},{-60,-60}, {0,20},{0,-20}, {50,50},{50,-50}, {100,80},{120,0},{100,-80}};


    
    private int[][] velocidad=new int[11][2];
    /**Retorna la fuerza de un jugador*/
    public int getFuerza(int n) {
        velocidad[n][0]=10-fuerza[n];
        return fuerza[n];
    }
    
    /**Retorna la velocidad de un jugador, en un equipo*/
    public int getVelocidad(int n,int e){
        return velocidad[n][e];
    }
    
    /**Retorna la coordenada x inicial del un jugador*/
    public int getXInicial(int n) {
        return posiciones[n][0];
    }
    
    /**Retorna la coordenada y inicial del un jugador*/
    public int getYInicial(int n) {
        return posiciones[n][1];
    }
    
    /**Retorna el angulo entre dos coordenadas*/
    private double angulo(double x1, double y1, double x0, double y0){
        return angulo(x1-x0,y1-x0);
    }
    
    /**Retorna el angulo de una cordenada*/
    private double angulo(double dx,double dy){
        double ang=0;
        if (dx>0) ang=Math.atan(dy/dx);
        else if (dx<0) ang=Math.atan(dy/dx)+Math.PI;
        else if (dx<0) ang=Math.PI/2;
        else ang=-Math.PI/2;
        ang=corregirAngulo(ang);
        return ang;
    }
    
    /**Uso interno*/
    private double corregirAngulo(double ang){
        while (ang<0)
            ang+=Math.PI*2;
        while (ang>=Math.PI*2)
            ang-=Math.PI*2;
        return ang;
    }
    
    /**Retorna la distancia entre dos coodenadas*/
    private double distancia(double x1,double y1,double x0,double y0){
        double dx=(x1-x0);
        double dy=(y1-y0);
        return distancia(dx,dy);
    }
    
    /**Retorna la distancia de una coordenada*/
    private double distancia(double dx,double dy){
        return Math.sqrt(dx*dx+dy*dy);
    }
    
    private boolean log=true;
    
    double d1,d0,a1,a0;
    Point pntB0=new Point(0,0);
    Point pntB1=new Point(0,0);
    Point pntB2=new Point(0,0);
    
    Point _pntB=new Point(0,0);
    Point _pntB0=new Point(0,0);
    Point _pntB1=new Point(0,0);
    Point _pntB2=new Point(0,0);
    int v;
    int c,_c0=0;
    int bx[],by[];
    int x[][]=new int[11][2];
    int y[][]=new int[11][2];
    int p[][]=new int[11][2];
    Vector vector=new Vector();
    Point[][] jug=new Point[11][2];
    boolean nn=true,nnn=false;
    boolean b0;
    
    /**Retorna las acciones a ejecutar*/
    public Vector<Comando> getComandos(SituacionJugadores sj) {
        vector.clear();
        nnn=false;
        
        for(int i=0;i<11;i++){
            
            jug[i][0]=sj.getMisJugadores()[i];
            jug[i][1]=sj.getContrario()[i];
        }
        
        pntB2=pntB1;

        b0=false;
        
        if (b0){
        	pntB0=_pntB0;
            
        }
        
        pntB1=pntB0; 
        _pntB1=pntB0;
        
        Point b=sj.getBola();
        
        pntB0=b;
       /* try{
        Class cc=Class.forName("futbol.Bola").getClass();
        System.out.println(cc);
       
        ((futbol.Bola)((Object)cc)).setXY(0,0);
        
        }catch(Exception e){
        System.out.println("NOP");
        System.out.println(e.getMessage());
        }*/
        
        a0=angulo(pntB2.x-pntB1.x,pntB2.y-pntB1.y);
        a1=angulo(pntB1.x-pntB0.x,pntB1.y-pntB0.y);
        d0=pntB1.distance(pntB0);//distancia(bx1,by1,bx0,by0);
        d1=pntB2.distance(pntB1);//distancia(bx2,by2,bx1,by1);
        
        nn=false;
        if (d0>3 && (Math.abs(a0-a1)>.20 || Math.abs(d1-d0)>5)){
            _pntB=pntB1;
            _c0=c-1;
        }
        
        //Calculamos v
        double n=(double)(c-_c0);
        double d=pntB0.distance(_pntB);//distancia(bx0,by0,_bx,_by);
        v=Math.max((int)Math.round(d/n-(n+1d)/2d),0);
        _pntB0=_pntB1;
        
        if (v>21){
        	_pntB0.y=(_pntB0.y<-MAXY)?-LONGY-_pntB0.y:0;
        	_pntB0.y=(_pntB0.y>MAXY)?LONGY-_pntB0.y:0;
            _pntB0.x=(_pntB0.x<-160)?-LONGX-_pntB0.x:0;
            _pntB0.x=(pntB0.x>160)?320-_pntB0.x:0;

          b0=true;}
        
        
        bx=new int[v+1];
        by=new int[v+1];
        
        bx[v]=pntB0.x;
        by[v]=pntB0.y;
        ganarPosicion();
        if (v>0){
            double dist=_pntB.distance(pntB0);//distancia(_bx,_by,bx0,by0);
            double dx=(double)(pntB0.x-_pntB.x)/dist;
            double dy=(double)(pntB0.y-_pntB.y)/dist;
            for(int i=v;i>0;i--){
                bx[i-1]=bx[i]+(int)Math.round(dx*(double)i);
                by[i-1]=by[i]+(int)Math.round(dy*(double)i);
                if (by[i-1]<-MAXY){
                    by[i-1]=-LONGY-by[i-1];dy=-dy;
                    if (i==v){
                    	_pntB.y=-LONGY-_pntB.y;pntB0.y=-LONGY-_pntB0.y;pntB1.y=-LONGY-_pntB1.y;pntB2.y=-LONGY-_pntB2.y;
                      
                    }
                }
                if (by[i-1]>MAXY){
                    by[i-1]=LONGY-by[i-1];dy=-dy;
                    if (i==v){
                    	_pntB.y=LONGY-_pntB.y;pntB0.y=LONGY-_pntB0.y;pntB1.y=LONGY-_pntB1.y;pntB2.y=LONGY-_pntB2.y;
                        
                    }
                }
                if (bx[i-1]<-MAXX){
                    bx[i-1]=-LONGX-bx[i-1];dx=-dx;
                    if (i==v){
                    	_pntB.x=-LONGX-_pntB.x;pntB0.x=-LONGX-_pntB0.x;pntB1.x=-LONGX-_pntB1.x;pntB2.x=-LONGX-_pntB2.x;
                    }
                }
                if (bx[i-1]>MAXX){
                    bx[i-1]=LONGX-bx[i-1];dx=-dx;
                    if (i==v){
                    	_pntB.x=LONGX-_pntB.x;pntB0.x=LONGX-_pntB0.x;pntB1.x=LONGX-_pntB1.x;pntB2.x=LONGX-_pntB2.x;
                    }
                }
            }
        }
        
        for(int i=0;i<11;i++){
            int jm=Math.max(Math.min(14,v-1),0);
            int bx_=sj.getMisJugadores()[i].x;
            int by_=sj.getMisJugadores()[i].y;
            d1=getVelocidad(i,0);
            p[i][0]=-1;
            for(int j=jm;j>0;j--){
                d0=Math.max(0,distancia(bx_,by_,bx[j],by[j])-10d)/d1;
                if (d0<(v-j)){
                    p[i][0]=v-j;
                    x[i][0]=bx[j];
                    y[i][0]=by[j];
                    break;
                }
            }
            if (p[i][0]==-1){
                d0=Math.max(0,distancia(bx_,by_,bx[0],by[0])-10d)/d1;
                if ((d0-Math.floor(d0))>0)
                    d0=Math.floor(d0)+1;
                else
                    d0=Math.floor(d0);
                p[i][0]=(int)d0;
                x[i][0]=bx[0];
                y[i][0]=by[0];
            }
        }
        tiropuerta(sj);
        ganarPosicion();
        tiropuerta(sj);
        paseInteligente();
        tiropuerta(sj);
        c++;
        return vector;
    }
    
    private void ganarPosicion(){
        int min=Integer.MAX_VALUE;
        for(int i=0;i<11;i++)
            if (p[i][0]<min)
                min=p[i][0];
        for(int i=0;i<11;i++)
            if (min==p[i][0])
                vector.add(new ComandoIrA(i,x[i][0],y[i][0]));
            else
                vector.add(new ComandoIrA(i,getXInicial(i),getYInicial(i)));
    }
    
    
    private int zonaMuerta[]={0,0,0,0,0,15,55,107};
    private void paseInteligente(){
        int mejor=0;
        int px=-1000;
        if (bx.length<=15){
            for(int i=0;i<11;i++){
                if (distancia(jug[i][0].x,jug[i][0].y,pntB0.x,pntB0.y)<=10){
                    
                    if (distancia(pntB0.x,pntB0.y,160,0)<=(zonaMuerta[getFuerza(i)]+20)){//+20
                        vector.add(new ComandoTiroAPuerta(i,0));//tiro a puerta
                    } else {
                        int next;
                        int it=0;
                        do{
                            while((next=rand.nextInt(11))==i);
                            it++;
                            if (jug[next][0].x>px){
                                px=jug[next][0].x;
                                mejor=next;
                            }
                        } while(jug[mejor][0].x<jug[i][0].x && it<100);
                        int dx=jug[mejor][0].x;
                        int dy=jug[mejor][0].y;
                        double dist=distancia(dx,dy,pntB0.x,pntB0.y);
                        int fuerza;
                        if (dist>90)
                            fuerza=7;
                        else if (dist>40)
                            fuerza=6;
                        else fuerza=4;
                        vector.add(chutear(i,jug[mejor][0].x,jug[mejor][0].y,fuerza));
                    }
                }
            }
        }
    }
    
    private void tiropuerta(SituacionJugadores sj){
    	
    	int portero=0;
    for (int n=0;n<11;n++){
    	if(n == portero){
    		//	ES EL PORTERO
    		boolean despejar = false;
    		for(int c=0;c<11;c++){
				if(sj.getContrario()[c].getY() < 75 && sj.getContrario()[c].getY() > -75 && sj.getContrario()[c].getX() < -40 ){
					despejar = true;
					break;
				}        			
    		}
    		if(despejar){
    			if(sj.getMisJugadores()[portero].getY() >= 0){
    				vector.add(new ComandoGolpearBola(portero,60,120));
    			}else{
    				vector.add(new ComandoGolpearBola(portero,60,-120));
    			}	
    		}else{
    			//	TIRA A PUERTA, NO NECESITA DESPEJAR PQ NO HAY RIVALES DELANTE
    			vector.add(new ComandoTiroAPuerta(portero,0));
    		}
    	}else{
    		//	ES UN JUGADOR
           	vector.add(new ComandoTiroAPuerta(n,0));
    	}
    }
    }
    
    
    private ComandoGolpearBola chutear(int nJug,int x,int y,int fuerza){
        double dx=x-jug[nJug][0].x;
        double dy=y-jug[nJug][0].y;
        if (dx!=0 && dy!=0){
            double dist=distancia(dx,dy);
            dx=dx/dist;dy=dy/dist;
            int f=Math.min(getFuerza(nJug),fuerza);
            double d=50d*(double)f/(double)getFuerza(nJug);
            double dd=d,ddx=dx,ddy=dy;
            int ff;
            do{
                dx=(int)((double)ddx*dd);
                dy=(int)((double)ddy*dd);
                dist=distancia(dx,dy);
                ff=getFuerza(nJug)*(int)dist/52;
                dd++;
            } while (ff<f);
            return new ComandoGolpearBola(nJug,jug[nJug][0].x+dx,jug[nJug][0].y+dy);
        } else
            return new ComandoGolpearBola(nJug,jug[nJug][0].x,jug[nJug][0].y);
    }
    
    private void beep(){
        //java.awt.Toolkit.getDefaultToolkit().beep();
    }
    
}

